package com.yex.service.modify.order;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.yex.common.exception.RRException;
import com.yex.dao.MerchantOrderDao;
import com.yex.entity.*;
import com.yex.entity.vo.MerchantOrderVo;
import com.yex.service.modify.BaseService;
import com.yex.service.modify.bank.BankService;
import com.yex.util.CommonModifyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class MerchantOrderService extends BaseService<MerchantOrderDao, MerchantOrderEntity> {
    @Autowired
    private UserPriceService userPriceService;

    @Autowired
    private BankService bankService;

    @Autowired
    private UserOrderService userOrderService;

    private MerchantOrderEntity _findById(Integer id) {
        MerchantOrderEntity merchantOrderEntity = new MerchantOrderEntity();
        merchantOrderEntity.setId(id);
        merchantOrderEntity = baseMapper.selectOne(merchantOrderEntity);
        if (merchantOrderEntity == null) throw new RRException("无效的订单信息");
        return merchantOrderEntity;
    }

    public MerchantOrderEntity findById(Integer id) {
        MerchantOrderEntity merchantOrderEntity = _findById(id);
        return merchantOrderEntity;
    }

    public void frozen(Integer id, BigDecimal frozen) {
        frozen = frozen.setScale(2, BigDecimal.ROUND_HALF_UP);
        MerchantOrderEntity merchantOrderEntity = _findById(id);
        if (merchantOrderEntity.getTotal().compareTo(frozen) < 0)
            throw new RRException("订单余额不足");
        EntityWrapper<MerchantOrderEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("id", id);
        merchantOrderEntity.setFrozen(merchantOrderEntity.getFrozen().add(frozen).setScale(2, BigDecimal.ROUND_HALF_UP));
        merchantOrderEntity.setTotal(merchantOrderEntity.getTotal().subtract(frozen).setScale(2, BigDecimal.ROUND_HALF_UP));
        Integer count = baseMapper.update(merchantOrderEntity, wrapper);
        if (count > 1) throw new RRException("冻结订单金额失败");
    }

    public void unFrozen(Integer id, BigDecimal frozen) {
        frozen = frozen.setScale(2, BigDecimal.ROUND_HALF_UP);
        MerchantOrderEntity merchantOrderEntity = _findById(id);
        merchantOrderEntity.setFrozen(merchantOrderEntity.getFrozen().subtract(frozen).setScale(2, BigDecimal.ROUND_HALF_UP));
        merchantOrderEntity.setTotal(merchantOrderEntity.getTotal().add(frozen).setScale(2, BigDecimal.ROUND_HALF_UP));
        EntityWrapper<MerchantOrderEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("id", id);
        Integer count = baseMapper.update(merchantOrderEntity, wrapper);
        if (count > 1) throw new RRException("冻结订单金额失败");
    }

    /**
     * 订单列表
     *
     * @param merchantOrderEntity
     * @param pageNumber          页码
     * @param rows                每页多少条
     * @param isUser              是否个人订单
     * @return
     */
    public Page<MerchantOrderVo> pageList(MerchantOrderEntity merchantOrderEntity, Integer pageNumber, Integer rows, boolean isUser) {
        Page<MerchantOrderVo> page = new Page<>(pageNumber, rows);
        if (isUser) {
            UserEntity userEntity = validateLoginUser(CommonModifyUtil.getRequest());
            merchantOrderEntity.setUserId(userEntity.getId());
        }
        return page.setRecords(baseMapper.selectListByPage(page, merchantOrderEntity));
    }

    public List<MerchantOrderEntity> findOrderByIds(List ids) {
        EntityWrapper<MerchantOrderEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("status", 0).eq("is_cancel", 0).in("id", ids);
        return baseMapper.selectList(wrapper);
    }

    /**
     * 创建订单写入数据库
     *
     * @param merchantOrderEntity
     * @return
     */
    private MerchantOrderEntity _createOrder(MerchantOrderEntity merchantOrderEntity) {
        //  创建用户订单相关信息
        merchantOrderEntity.setCreateTime(new Date());
        merchantOrderEntity.setFrozen(BigDecimal.ZERO);
        merchantOrderEntity.setIsCancel(0);
        merchantOrderEntity.setStatus(0);
        Integer count = baseMapper.insert(merchantOrderEntity);
        if (count > 1) throw new RRException("创建订单失败");
        return merchantOrderEntity;
    }

    /**
     * 创建订单
     *
     * @param merchantOrderEntity
     * @return
     */
    public MerchantOrderEntity createOrder(MerchantOrderEntity merchantOrderEntity) {
        if (merchantOrderEntity.getBankId() == null) {
            BankEntity bankEntity = bankService.getDefaultBank();
            merchantOrderEntity.setBankId(bankEntity.getId());
        }
        switch (merchantOrderEntity.getOrderType()) {
            case 1:
                return createBuyOrder(merchantOrderEntity);
            case 2:
                return createSellerOrder(merchantOrderEntity);
            default:
                throw new RRException("无效的订单类型");
        }
    }

    /**
     * 创建卖单
     *
     * @param merchantOrderEntity
     * @return
     */
    public MerchantOrderEntity createSellerOrder(MerchantOrderEntity merchantOrderEntity) {
        UserEntity userEntity = validateLoginUser(CommonModifyUtil.getRequest());
        if (userEntity.getMerchantState() != 2) throw new RRException("只有商家才能发起订单交易");
        //  如果当前订单金额比用户余额大
        if (merchantOrderEntity.getTotal().compareTo(userEntity.getTotal()) > 0) throw new RRException("当前余额不足");
        //  冻结用户余额
        userPriceService.frozen(userEntity.getId(), merchantOrderEntity.getTotal());
        merchantOrderEntity.setUserId(userEntity.getId());
        return _createOrder(merchantOrderEntity);
    }

    /**
     * 创建买单
     *
     * @param merchantOrderEntity
     * @return
     */
    public MerchantOrderEntity createBuyOrder(MerchantOrderEntity merchantOrderEntity) {
        UserEntity userEntity = validateLoginUser(CommonModifyUtil.getRequest());
        if (userEntity.getMerchantState() != 2) throw new RRException("只有商家才能发起订单交易");
        //  创建用户订单相关信息
        merchantOrderEntity.setUserId(userEntity.getId());
        return _createOrder(merchantOrderEntity);
    }

    public void completeOrder(Integer orderId) {
        MerchantOrderEntity merchantOrderEntity = findById(orderId);
        if (merchantOrderEntity.getStatus() == 1) throw new RRException("该订单已完成");
        if (merchantOrderEntity.getIsCancel() == 1) throw new RRException("该订单已被撤销");
        merchantOrderEntity.setStatus(1);
        EntityWrapper<MerchantOrderEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("id", orderId);
        Integer count = baseMapper.update(merchantOrderEntity, wrapper);
        if (count > 1) throw new RRException("完成订单失败");
    }


    public void cancelOrder(Integer id) {
        UserEntity userEntity = validateLoginUser(CommonModifyUtil.getRequest());
        MerchantOrderEntity merchantOrderEntity = findById(id);
        if (merchantOrderEntity.getUserId().compareTo(userEntity.getId()) != 0) throw new RRException("无效的订单信息");
        if (merchantOrderEntity.getIsCancel() == 1) throw new RRException("订单已被撤销");
        if (merchantOrderEntity.getStatus() == 1) throw new RRException("该订单已完成");
        //  得到当前挂单关联的用户订单信息
        List<UserOrderEntity> userOrderEntities = userOrderService.getOrderByOrderId(id);
        //  撤销所有关联的用户订单
        for (UserOrderEntity item : userOrderEntities) {
            if (item.getStatus() == 0 && item.getIsCancel() == 0) {
                userOrderService.cancelOrderLogic(item, merchantOrderEntity);
            }
        }
        //  重新获取订单信息
        merchantOrderEntity = findById(id);
        //  如果挂单是个卖单,那么将冻结余额归还给用户
        if (merchantOrderEntity.getOrderType() == 2) {
            userPriceService.unfrozen(userEntity.getId(), merchantOrderEntity.getTotal());
        }
        //  修改订单状态
        EntityWrapper<MerchantOrderEntity> wrapper = new EntityWrapper<>();
        wrapper.eq("id", id).eq("user_id", userEntity.getId());
        merchantOrderEntity.setIsCancel(1);
        Integer count = baseMapper.update(merchantOrderEntity, wrapper);
        if (count > 1) throw new RRException("取消订单失败");
    }

}
